home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 1 / Amiga Tools.iso / viren / virusx / source / lamer.c next >
C/C++ Source or Header  |  1994-06-06  |  5KB  |  227 lines

  1. /**********************************************************************/
  2. /*       Code to check for, and remove, the Lamer Revenge Virus       */
  3. /*                       This code by Dan James                       */
  4. /**********************************************************************/
  5.  
  6. #include <exec/types.h>
  7. #include <exec/exec.h>
  8. #include <exec/execbase.h>
  9. #include <exec/resident.h>
  10.  
  11. #include <libraries/dos.h>
  12. #include <devices/trackdisk.h>
  13. #include <stdio.h>
  14. #include <ctype.h>
  15. #include <string.h>
  16. #include <proto/all.h>
  17. #include "virusx.i"
  18.  
  19. #define ROOT            880L
  20. #define HASHCHAIN        124
  21. #define OK            0
  22. #define WRITE_PROTECTED     1
  23. #define NO_DISK            2
  24.  
  25. UBYTE *diskdata = 0;
  26. UBYTE invisible[] = "DF0:\240\240\240\240\240";
  27. UBYTE newfile[] = "DF0:DANGERVIRUS";
  28.  
  29. unsigned long CheckSum(unsigned long block[]);
  30.  
  31. extern char TDName[];
  32. extern struct  IOStdReq *diskreq;              /* trackdisk's IOStdReq         */
  33. extern struct Window           *Window;
  34.  
  35. void
  36. CheckDiskForRLamer(int num)
  37. {
  38.     char buf[255];
  39.     int i;
  40.     long *buff, Virus = 0, block, link = 0, before = 0, after = 0;
  41.     unsigned long lock;
  42.     char drive[5];
  43.  
  44.         if(OpenDevice(TDName,(long)num,diskreq,0L))
  45.         return;
  46.  
  47.     /** Check for No Disk **/
  48.  
  49.     invisible[2] = newfile[2] = 0x30 + num;
  50.  
  51.     if((lock = Lock(invisible,ACCESS_READ)) == DOSFALSE)
  52.         return;
  53.  
  54.     UnLock(lock);
  55.  
  56.     strncpy(drive,invisible,4); drive[4] = 0;
  57.  
  58.     strcpy(buf, "CAUTION!|RLamer Virus found on Drive DF0:|Disk is Write Protected.");
  59.     buf[39] = num + '0';
  60.  
  61.     while (ProtStatus() == TRUE)
  62.         if (SimpleRequest(buf, "Retry|Cancel", Window, 0) == 1) return;
  63.  
  64.     if(Rename(invisible,newfile) == DOSFALSE)
  65.         {
  66.         strcat(buf, "Attempt to rename virus Failed.|Your disk has an invisible file on it,|which contains this virus.");
  67.         SimpleRequest(buf, "Thanks for the Warning", Window, 0);
  68.         return;
  69.         }
  70.         else
  71.         {
  72.         strcat(buf, "The virus has been renamed to the root directory|of that disk, as 'DANGERVIRUS'.|Please Delete this file, and edit your|Startup-Sequence to remove the invisible filename|found on the first line.");
  73.         SimpleRequest(buf, "Will Do", Window, 0);
  74.         }
  75.  
  76. /* virus is present */
  77.  
  78.     ReadBlock(ROOT);
  79.  
  80.     buff = (long *)diskdata;
  81.  
  82.     Virus = buff[ 15 ];
  83.  
  84.     for(i = 14; i > 6; i--)
  85.         if(before = buff[ i ])
  86.             break;
  87.  
  88.     if(before == 0)
  89.         return;
  90.  
  91.     for(i = 16; i < 81; i++)
  92.         if(after = buff[ i ])
  93.             break;
  94.  
  95.     if(after == 0)
  96.         return;
  97.  
  98.     block = before;
  99.  
  100.     do     {
  101.         ReadBlock(block);
  102.  
  103.         link = buff[ HASHCHAIN ];
  104.  
  105.         if(link == after)
  106.             {
  107.             buff[ HASHCHAIN ] = buff[ 5 ] = 0;
  108.             buff[ 5 ] = CheckSum(buff);
  109.             WriteBlock(block);
  110.             break;
  111.             }
  112.         } while(block = link);
  113.  
  114.     CloseDevice(diskreq);
  115. }
  116.  
  117. unsigned long 
  118. CheckSum(unsigned long block[])
  119. {
  120.     int cnt;
  121.     unsigned long sum = 0;
  122.     for(cnt = 0; cnt < 128; cnt++)
  123.         sum += block[ cnt ];
  124.     return (~sum + 1);
  125. }
  126.  
  127. /**********************************************************************/
  128. /*   This code will detect one varient of the Lamer virus in memory   */
  129. /*  and deactivate it.  Currently no borrowed vectors are restored.   */
  130. /*                   A reboot would fix that though                   */
  131. /**********************************************************************/
  132.  
  133. #define LAMER_ID    "clist 33.80"
  134.  
  135. void
  136. CheckRamForLamer(void)
  137. {
  138.     struct ExecBase **ExecBase = (struct ExecBase **)4;
  139.     APTR *KTagPtr = (APTR *)(*ExecBase)->KickTagPtr;
  140.     APTR Lamer, TestKTag();
  141.  
  142.     while(*KTagPtr)
  143.         {
  144.         while((ULONG)*KTagPtr & 0x80000000)
  145.             KTagPtr = (APTR *)((ULONG)*KTagPtr & 0x7FFFFFFF);
  146.  
  147.         if(Lamer = TestKTag( *KTagPtr ))
  148.             {
  149.             SimpleRequest("The Lamer Revenge Virus was found in RAM,|and is now disabled.", " Thanks ", Window, 0);
  150.             if(KillLamer(Lamer))
  151.                 *KTagPtr = (APTR)((ULONG)(KTagPtr+1) | 0x80000000);
  152.             return;
  153.             }
  154.         KTagPtr++;
  155.         }
  156. }
  157.  
  158. int
  159. KillLamer(APTR addr)
  160. {
  161. #define    RTS    0x70014E75    /* moveq.l  #1,d0   rts */
  162.     int i;
  163.     APTR ptr;
  164.  
  165. /*
  166.     I think that the Lamer is in memory.  I'm going to test several
  167.     locations within the virus body to be sure that it is the exact
  168.     virus I'm familiar with.  The test array has memory offsets from
  169.     addr and the contents I expect to see there.
  170. */
  171. static    APTR test[] = 
  172.         {
  173.         (APTR)0x0A6, (APTR)0x2F3A0EEC,    /* SumKick routine */
  174.         (APTR)0x166, (APTR)0x2F3A0E3C,    /* DoIO routine */
  175.         (APTR)0x246, (APTR)0x2F3A0D64,    /* TDRead routine */
  176.         (APTR)0x2B8, (APTR)0x287A0D0C,    /* Trigger point */
  177.         (APTR)0x5AE, (APTR)0x2C780004    /* Disk Trasher */
  178.         };
  179.  
  180. /*
  181.     I'm going to pull the vipers fangs by placing RTS instructions in
  182.     key areas.  One area is his Resident Initialization vector - that'll
  183.     stop him from living through a re-boot (provided he's not on the
  184.     boot disk that is)
  185. */
  186. static    APTR rts[] = 
  187.         {
  188.         (APTR)0,        /* Keep from initializing on reset */
  189.         (APTR)0x2B8,        /* disable one trigger point */
  190.         (APTR)0x5AE,        /* stop the disk trasher */
  191.         (APTR)0x6D8,        /* stop the alerts */
  192.         (APTR)0x73C        /* his ReBoot exit */
  193.         };
  194.  
  195.     for(i = 0; i < sizeof(test)/sizeof(ULONG); i+= 2)
  196.         {
  197.         ptr = (long)addr+(long)test[ i ];
  198.         if( (long)*ptr != (long)test[ i+1 ] )
  199.             return 0;
  200.         }
  201.  
  202.     for(i = 0; i < sizeof(rts)/sizeof(ULONG); i++)
  203.         {
  204.         ptr = (long)addr+(long)rts[ i ];
  205.         *ptr = (APTR)RTS;
  206.         }
  207.  
  208.     return 1;
  209. }
  210.  
  211. /*
  212.     Test the Resident structure ID string to see if it matches the one
  213.     the Lamer uses.  Return the structures Init vector if true, NULL if
  214.     not
  215. */
  216. APTR 
  217. TestKTag( struct Resident *res )
  218. {
  219.     char str[12];
  220.  
  221.     strncpy(str,res->rt_IdString,11); 
  222.     str[11] = 0;
  223.     if(strcmp(LAMER_ID,str) == 0)
  224.         return res->rt_Init;
  225.     return (APTR)NULL;
  226. }
  227.